import logging
from core.RPC import REMOTE_SERVICE, LoadRpc  # R,
from core.config import cfg
from rest_framework.request import Request
from threading import Thread
from django.utils.timezone import datetime, timedelta
from TDhelper.Event.webEvent.Events import Manager
from TDhelper.web.utils.permission.server import regist_permission
from TDhelper.web.utils.permission.client import validate_permission

import time
# get config
EVENT_CONFIG = {"state": -1, "msg": {"host": [""], "token": None}}
try:
    EVENT_CONFIG = REMOTE_SERVICE.REMOTE_CONFIG.CONFIGS_GETCFG(
        **{"key": cfg.SERVICE_EVENT})
except Exception as e:
    logging.error(e)
    EVENT_CONFIG = {"state": -1, "msg": {"host": [""], "token": None}}

# Event manager class.
# Function <object>.on will trigger event.
# Decorate function <object>.monitor will listen event.
try:
    EVENT_MANAGER = Manager(EVENT_CONFIG['msg']['host'],
                            cfg.SERVICE_KEY,
                            REMOTE_SERVICE,
                            EVENT_CONFIG['msg']['token']
                            ) if EVENT_CONFIG["state"] == 200 else Manager("", cfg.SERVICE_KEY, REMOTE_SERVICE, "")
except Exception as e:
    EVENT_MANAGER = None
    
# Permisson manager class.
PERMISSION_MANAGER = validate_permission(Request,cfg.SERVICE_KEY)
if REMOTE_SERVICE:
    PERMISSION_MANAGER.set_permission_handle(
        handle= REMOTE_SERVICE,
        permission_service_key="PERMISSION_CENTER",
        func_name= "PERMISSION_COLLECTS_VALIDATE_AUTHORIZED")
    
# app assess token
'''
class application_token_mangement:
    __token__ = None
    __expire__ = None
    __handle__ = None
    __renewal_state__ = True
    __renewal_time_sleep__ = 60

    def __init__(self):
        self.__token__ = ''
        self.__expire__ = datetime.now().__add__(timedelta(
            days=1
        ))

    def configure(self, handle, renewal_monitor_speed=None):
        self.__handle__ = handle
        self.__renewal_time_sleep__ = renewal_monitor_speed if renewal_monitor_speed else self.__renewal_time_sleep__

    def auto_renewal_token(self):
        if self.__handle__:
            while (self.__renewal_state__):
                try:
                    result = {"state": -1,
                              "msg": {"token": "", "expire": None}}
                    if self.expire:
                        if datetime.now().__add__(timedelta(seconds=2*self.__renewal_time_sleep__)) > self.expire:
                            result = self.__handle__.APP_GET_APP_ACCESS_TOKEN(**{
                                "headers": {
                                    "HTTP-APP-ID": cfg.APP_ID,
                                    "HTTP-SECRET": cfg.APP_SECRET
                                }
                            })
                    else:
                        result = self.__handle__.APP_GET_APP_ACCESS_TOKEN(**{
                            "headers": {
                                "HTTP-API-ID": cfg.APP_ID,
                                "HTTP-SECRET": cfg.APP_SECRET
                            }
                        })
                    if result.get('state', False) == 200:
                        self.__token__ = result.get('msg').get("token")
                        self.__expire__ = result.get('msg').get("expire")
                except Exception as e:
                    logging.error(e)
                time.sleep(self.__renewal_time_sleep__)
        else:
            logging.error("handle has none.")

    def star_monitor(self):
        self.__renewal_state__ = True
        monitor = Thread(target=self.auto_renewal_token)
        monitor.start()

    def stop_monitor(self):
        self.__renewal_state__ = False

    @property
    def token(self):
        return self.__token__

    @property
    def expire(self):
        return self.__expire__
APPLICATION_TOKEN = application_token_mangement()

if 'DEVELOPER' not in REMOTE_SERVICE:
    if REMOTE_SERVICE.DEVELOPER:
        # auto get app token.
        # rpc can use general token to access. if rpc service enable safe mode, app must use dynamic token.
        #APPLICATION_TOKEN.configure(REMOTE_SERVICE.DEVELOPER)
        pass
else:
    raise Exception('rpc not found developer service.')
'''

class server_cmd:
    command_mapping = {}

    def __init__(self, cmd_cnf=None):
        if cmd_cnf:
            # todo load by configure file
            pass
            #self.command_mapping = cmd_cnf
    def __method__(self,func,*args,**kwargs):
        return func(*args,**kwargs)
        
    def add_cmd(self, cmd, method=None):
        if cmd.lower() not in self.command_mapping:
            self.command_mapping[cmd.lower()] = method
    
    def override_call(self, cmd, method):
        self.command_mapping[cmd.lower()] = method
    
    def todo(self, cmd: str, *args, **kwargs):
        if cmd.lower() in self.command_mapping:
            if(self.command_mapping[cmd.lower()]):
                try:
                    return self.command_mapping[cmd.lower()](*args, **kwargs)
                except Exception as e:
                    logging.error(e)
                    return False, e.args[1]
            else:
                logging.error("cmd method is none.")
                return False,"cmd method(%s) is none."%cmd.lower()
        else:
            logging.error("not found cmd '%s'" % cmd.lower())
            return False, "not found cmd '%s'" % cmd.lower()
            
cmd = server_cmd()
cmd.add_cmd("load_rpc",LoadRpc)